﻿using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Design;
using System.Globalization;
using System.Text;
using System.Windows.Forms;

namespace AdvancedDataGridView
{
	[ToolboxItem(false)]
	[DesignTimeVisible(false)]
	public class TreeGridNode : DataGridViewRow
	{
		internal TreeGridNode(TreeGridView owner) : this()
		{
			this._grid = owner;
			this.IsExpanded = true;
		}

		public TreeGridNode()
		{
			this._index = -1;
			this._level = -1;
			this.IsExpanded = false;
			this.UniqueValue = this.rndSeed.Next();
			this._isSited = false;
			this._isFirstSibling = false;
			this._isLastSibling = false;
			this._imageIndex = -1;
		}

		public override object Clone()
		{
			TreeGridNode treeGridNode = (TreeGridNode)base.Clone();
			treeGridNode.UniqueValue = -1;
			treeGridNode._level = this._level;
			treeGridNode._grid = this._grid;
			treeGridNode._parent = this.Parent;
			treeGridNode._imageIndex = this._imageIndex;
			if (treeGridNode._imageIndex == -1)
			{
				treeGridNode.Image = this.Image;
			}
			treeGridNode.IsExpanded = this.IsExpanded;
			return treeGridNode;
		}

		protected internal virtual void UnSited()
		{
			foreach (object obj in this.Cells)
			{
				DataGridViewCell dataGridViewCell = (DataGridViewCell)obj;
				TreeGridCell treeGridCell = dataGridViewCell as TreeGridCell;
				if (treeGridCell != null)
				{
					treeGridCell.UnSited();
				}
			}
			this._isSited = false;
		}

		protected internal virtual void Sited()
		{
			this._isSited = true;
			this.childCellsCreated = true;
			Debug.Assert(this._grid != null);
			foreach (object obj in this.Cells)
			{
				DataGridViewCell dataGridViewCell = (DataGridViewCell)obj;
				TreeGridCell treeGridCell = dataGridViewCell as TreeGridCell;
				if (treeGridCell != null)
				{
					treeGridCell.Sited();
				}
			}
		}

		[Browsable(false)]
		[Description("Represents the index of this row in the Grid. Advanced usage.")]
		[EditorBrowsable(EditorBrowsableState.Advanced)]
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public int RowIndex
		{
			get
			{
				return base.Index;
			}
		}

		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		[Browsable(false)]
		public new int Index
		{
			get
			{
				if (this._index == -1)
				{
					this._index = this._owner.IndexOf(this);
				}
				return this._index;
			}
			internal set
			{
				this._index = value;
			}
		}

		[Browsable(false)]
		[EditorBrowsable(EditorBrowsableState.Never)]
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public ImageList ImageList
		{
			get
			{
				ImageList result;
				if (this._grid != null)
				{
					result = this._grid.ImageList;
				}
				else
				{
					result = null;
				}
				return result;
			}
		}

		private bool ShouldSerializeImageIndex()
		{
			return this._imageIndex != -1 && this._image == null;
		}

		[DefaultValue(-1)]
		[Description("...")]
		[Editor("System.Windows.Forms.Design.ImageIndexEditor", typeof(UITypeEditor))]
		[TypeConverter(typeof(ImageIndexConverter))]
		[Category("Appearance")]
		public int ImageIndex
		{
			get
			{
				return this._imageIndex;
			}
			set
			{
				this._imageIndex = value;
				if (this._imageIndex != -1)
				{
					this._image = null;
				}
				if (this._isSited)
				{
					this._treeCell.UpdateStyle();
					if (this.Displayed)
					{
						this._grid.InvalidateRow(this.RowIndex);
					}
				}
			}
		}

		private bool ShouldSerializeImage()
		{
			return this._imageIndex == -1 && this._image != null;
		}

		public Image Image
		{
			get
			{
				Image result;
				if (this._image == null && this._imageIndex != -1)
				{
					if (this.ImageList != null && this._imageIndex < this.ImageList.Images.Count)
					{
						result = this.ImageList.Images[this._imageIndex];
					}
					else
					{
						result = null;
					}
				}
				else
				{
					result = this._image;
				}
				return result;
			}
			set
			{
				this._image = value;
				if (this._image != null)
				{
					this._imageIndex = -1;
				}
				if (this._isSited)
				{
					this._treeCell.UpdateStyle();
					if (this.Displayed)
					{
						this._grid.InvalidateRow(this.RowIndex);
					}
				}
			}
		}

		protected override DataGridViewCellCollection CreateCellsInstance()
		{
			DataGridViewCellCollection dataGridViewCellCollection = base.CreateCellsInstance();
			dataGridViewCellCollection.CollectionChanged += this.cells_CollectionChanged;
			return dataGridViewCellCollection;
		}

		private void cells_CollectionChanged(object sender, CollectionChangeEventArgs e)
		{
			if (this._treeCell == null)
			{
				if (e.Action == CollectionChangeAction.Add || e.Action == CollectionChangeAction.Refresh)
				{
					TreeGridCell treeGridCell = null;
					if (e.Element == null)
					{
						foreach (object obj in base.Cells)
						{
							DataGridViewCell dataGridViewCell = (DataGridViewCell)obj;
							if (dataGridViewCell.GetType().IsAssignableFrom(typeof(TreeGridCell)))
							{
								treeGridCell = (TreeGridCell)dataGridViewCell;
								break;
							}
						}
					}
					else
					{
						treeGridCell = (e.Element as TreeGridCell);
					}
					if (treeGridCell != null)
					{
						this._treeCell = treeGridCell;
					}
				}
			}
		}

        //[Category("Data")]
        //[Description("The collection of root nodes in the treelist.")]
        //[Editor(typeof(System.ComponentModel.Design.CollectionEditor), typeof(UITypeEditor))]
        //[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
		public TreeGridNodeCollection Nodes
		{
			get
			{
				if (this.childrenNodes == null)
				{
					this.childrenNodes = new TreeGridNodeCollection(this);
				}
				return this.childrenNodes;
			}
			set
			{
			}
		}

		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		[Browsable(false)]
		public new DataGridViewCellCollection Cells
		{
			get
			{
				if (!this.childCellsCreated && base.DataGridView == null)
				{
					if (this._grid == null)
					{
						return null;
					}
					base.CreateCells(this._grid);
					this.childCellsCreated = true;
				}
				return base.Cells;
			}
		}

		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		[Browsable(false)]
		public int Level
		{
			get
			{
				if (this._level == -1)
				{
					int num = 0;
					for (TreeGridNode parent = this.Parent; parent != null; parent = parent.Parent)
					{
						num++;
					}
					this._level = num;
				}
				return this._level;
			}
		}

		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		[Browsable(false)]
		public TreeGridNode Parent
		{
			get
			{
				return this._parent;
			}
		}

		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		[Browsable(false)]
		public virtual bool HasChildren
		{
			get
			{
				return this.childrenNodes != null && this.Nodes.Count != 0;
			}
		}

		[Browsable(false)]
		public bool IsSited
		{
			get
			{
				return this._isSited;
			}
		}

		[Browsable(false)]
		public bool IsFirstSibling
		{
			get
			{
				return this.Index == 0;
			}
		}

		[Browsable(false)]
		public bool IsLastSibling
		{
			get
			{
				TreeGridNode parent = this.Parent;
				return parent == null || !parent.HasChildren || this.Index == parent.Nodes.Count - 1;
			}
		}

		public virtual bool Collapse()
		{
			return this._grid.CollapseNode(this);
		}

		public virtual bool Expand()
		{
			bool result;
			if (this._grid != null)
			{
				result = this._grid.ExpandNode(this);
			}
			else
			{
				this.IsExpanded = true;
				result = true;
			}
			return result;
		}

		protected internal virtual bool InsertChildNode(int index, TreeGridNode node)
		{
			node._parent = this;
			node._grid = this._grid;
			if (this._grid != null)
			{
				this.UpdateChildNodes(node);
			}
			if ((this._isSited || this.IsRoot) && this.IsExpanded)
			{
				this._grid.SiteNode(node);
			}
			return true;
		}

		protected internal virtual bool InsertChildNodes(int index, params TreeGridNode[] nodes)
		{
			foreach (TreeGridNode node in nodes)
			{
				this.InsertChildNode(index, node);
			}
			return true;
		}

		protected internal virtual bool AddChildNode(TreeGridNode node)
		{
			node._parent = this;
			node._grid = this._grid;
			if (this._grid != null)
			{
				this.UpdateChildNodes(node);
			}
			if ((this._isSited || this.IsRoot) && this.IsExpanded && !node._isSited)
			{
				this._grid.SiteNode(node);
			}
			return true;
		}

		protected internal virtual bool AddChildNodes(params TreeGridNode[] nodes)
		{
			foreach (TreeGridNode node in nodes)
			{
				this.AddChildNode(node);
			}
			return true;
		}

		protected internal virtual bool RemoveChildNode(TreeGridNode node)
		{
			if ((this.IsRoot || this._isSited) && this.IsExpanded)
			{
				this._grid.UnSiteNode(node);
			}
			node._grid = null;
			node._parent = null;
			return true;
		}

		protected internal virtual bool ClearNodes()
		{
			if (this.HasChildren)
			{
				for (int i = this.Nodes.Count - 1; i >= 0; i--)
				{
					this.Nodes.RemoveAt(i);
				}
			}
			return true;
		}

		[Browsable(false)]
		[EditorBrowsable(EditorBrowsableState.Advanced)]
		public event EventHandler Disposed
		{
			add
			{
				this.disposed = (EventHandler)Delegate.Combine(this.disposed, value);
			}
			remove
			{
				this.disposed = (EventHandler)Delegate.Remove(this.disposed, value);
			}
		}

		[Browsable(false)]
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public ISite Site
		{
			get
			{
				return this.site;
			}
			set
			{
				this.site = value;
			}
		}

		private void UpdateChildNodes(TreeGridNode node)
		{
			if (node.HasChildren)
			{
				foreach (TreeGridNode treeGridNode in node.Nodes)
				{
					treeGridNode._grid = node._grid;
					this.UpdateChildNodes(treeGridNode);
				}
			}
		}

		public override string ToString()
		{
			StringBuilder stringBuilder = new StringBuilder(36);
			stringBuilder.Append("TreeGridNode { Index=");
			stringBuilder.Append(this.RowIndex.ToString(CultureInfo.CurrentCulture));
			stringBuilder.Append(" }");
			return stringBuilder.ToString();
		}

		internal TreeGridView _grid;

		internal TreeGridNode _parent;

		internal TreeGridNodeCollection _owner;

		internal bool IsExpanded;

		internal bool IsRoot;

		internal bool _isSited;

		internal bool _isFirstSibling;

		internal bool _isLastSibling;

		internal Image _image;

		internal int _imageIndex;

		private Random rndSeed = new Random();

		public int UniqueValue = -1;

		private TreeGridCell _treeCell;

		private TreeGridNodeCollection childrenNodes;

		private int _index;

		private int _level;

		private bool childCellsCreated = false;

		private ISite site = null;

		private EventHandler disposed = null;
	}
}
